package tools

import (
	{{if eq .isUser true}}"errors"{{end}}
	"context"
	"fmt"
	{{if eq .isUser true}}"github.com/dgrijalva/jwt-go"{{end}}
	{{if eq .isUser true}}"{{.projectName}}/model"{{end}}
	"{{.projectName}}/variable"
	"os"
    "os/exec"
	"strings"
	{{if eq .isUser true}}"time"{{end}}
    "regexp"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/apache/rocketmq-client-go/v2/consumer"
)

type Tools struct {

}

func NewTools() *Tools {
	return &Tools{}
}

func (t *Tools) Capitalize(str string) string {
	var upperStr string
	vv := []rune(str)
	for i := 0; i < len(vv); i++ {
		if i == 0 {
			if vv[i] >= 97 && vv[i] <= 122 {
				vv[i] -= 32
				upperStr += string(vv[i])
			} else {
				fmt.Println("Not begins with lowercase letter,")
				return str
			}
		} else {
			upperStr += string(vv[i])
		}
	}
	return upperStr
}

func (t *Tools) Lower(s string) string {
	if len(s) > 0 {
		return strings.ToLower(string(s[0])) + s[1:]
	}
	return s
}

func (t *Tools) Exists(path string) bool {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		return false
	}
	return true
}

func (t *Tools) ToSnake(str string) string {
	str = regexp.MustCompile(`[^a-zA-Z0-9]+`).ReplaceAllString(str, "_")                 //非常规字符转化为 _
	snake := regexp.MustCompile("(.)([A-Z][a-z]+)").ReplaceAllString(str, "${1}_${2}")   //拆分出连续大写
	snake = regexp.MustCompile("([a-z0-9])([A-Z])").ReplaceAllString(snake, "${1}_${2}") //拆分单词
	return strings.ToLower(snake)                                                        //全部转小写
}

{{- if eq .isUser true}}
const TokenExpireDuration = time.Hour * 2

var MemberSecret = []byte("Y29kZUdlbmVyYXRvcg==")

type MemberClaims struct {
	UserId   int64  `json:"userid"`
	Username string `json:"username"`
	Password string `json:"password"`
	jwt.StandardClaims
}

// GenToken 生成JWT
func (t *Tools) GenToken(user *model.{{.structName}}) (string, int64, error) {
	// 创建一个我们自己的声明
	c := MemberClaims{
		user.Id, // 自定义字段
		user.Username,
		user.Password,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
			Issuer:    "field-project",                            // 签发人
		},
	}
	// 使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	// 使用指定的secret签名并获得完整的编码后的字符串token
	tokenString, err := token.SignedString(MemberSecret)

	return tokenString, c.ExpiresAt, err
}

// ParseToken 解析JWT
func (t *Tools) ParseToken(tokenString string) (*MemberClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &MemberClaims{}, func(token *jwt.Token) (i interface{}, err error) {
		return MemberSecret, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*MemberClaims); ok && token.Valid { // 校验token
		return claims, nil
	} else if ve, ok := err.(jwt.ValidationError); ok {
		if ve.Errors&jwt.ValidationErrorMalformed != 0 {
			fmt.Println("错误的token")
		} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
			fmt.Println(" token过期或未启用")
		} else {
			fmt.Println("Could not handle this token:", err)
		}
	} else {
		fmt.Println("无法解析此token", err)
	}

	return nil, errors.New("invalid token")
}
{{end}}

func (t *Tools) RocketMQSendMessage(body string) string {
	err := variable.PRODUCE.Start()
	if err != nil {
		fmt.Println("err：", err)
		return ""
	}

	msg := &primitive.Message{
		Topic: "topic",
		Body:  []byte(body),
	}
	msg.WithTag("tag")
	msg.WithKeys([]string{"key"})
	// 发送消息
	result, _ := variable.PRODUCE.SendSync(context.Background(), msg)
	return result.String()
}

func (t *Tools) RocketMQReceiveMessage() []string {
	var message_list []string
	variable.CONSUMER.Subscribe("topic", consumer.MessageSelector{}, func(ctx context.Context, msg ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
		for _, v := range msg {
			fmt.Println("Body：", string(v.Body))
			message_list = append(message_list, string(v.Body)) // v.Body : 消息主体
		}
		return consumer.ConsumeSuccess, nil
	})

	err := variable.CONSUMER.Start()
	if err != nil {
		fmt.Println("err：", err)
		return nil
	}

	return message_list
}

func (t *Tools) CommandLine(dir string, name string, args ...string) {
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		fmt.Println("cmd run err：", err)
	}
}



